package kit.views;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.LinkedList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import kit.core.Core;
import kit.core.ShellException;
import kit.persistency.KitDB;
import javax.swing.JLabel;
import java.awt.Font;
import java.awt.FlowLayout;
import javax.swing.JTextArea;
import javax.swing.UIManager;

public class KitFrame extends JFrame {

	private JPanel contentPane;
	private JMenu mnFile;
	private JMenu mnSegreti;
	private JMenu mnRound;
	private JPanel centerPanel;
	private JMenuItem mntmNuovoRound;
	private JList secrectList;
	private JList secrectList_1;
	private JMenuItem mntmGeneraDomanda;
	private JPanel panel_1;
	private JTextArea txtrItsOver;
	private JMenuItem mntmGeneraRisposta;
	private JMenuItem mntmConcludiRound;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					KitFrame frame = new KitFrame();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public KitFrame() {
		setResizable(false);
		setMinimumSize(new Dimension(600, 450));
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowActivated(WindowEvent e) {
				populateQuestionsList();
				
			}
		});
		setTitle("KIT");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 450, 300);

		JMenuBar menuBar = new JMenuBar();
		setJMenuBar(menuBar);

		mnFile = new JMenu("File");
		menuBar.add(mnFile);

		JMenuItem mntmEsci = new JMenuItem("Esci");
		mntmEsci.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				System.exit(0);
			}
		});

		mntmNuovoRound = new JMenuItem("Nuova verifica");
		mntmNuovoRound.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Core core = Core.obtainSingleton();
				if (core.isChallengeRunning()) {
					if (JOptionPane
							.showConfirmDialog(
									null,
									"Al momento una verifica è in corso.\nIniziarne una nuova?",
									"Nuova verifica",
									JOptionPane.OK_CANCEL_OPTION) != 0) {
						return;
					}
				}		
				SenderReceiverPanel srPanel = new SenderReceiverPanel();
				List<String> UIDs;
				try {
					UIDs = core.getPrivateKeysUID();
					for (String UID : UIDs) {
						srPanel.getSenderComboBox().addItem(UID);
					}
					UIDs = core.getPublicKeysUID();
					for (String UID : UIDs) {
						srPanel.getReceiverComboBox().addItem(UID);
					}
					srPanel.getSenderComboBox().repaint();
				} catch (IOException | InterruptedException | ShellException ee) {
					JOptionPane.showMessageDialog(KitFrame.this, ee.getMessage(),
							"Errore", JOptionPane.ERROR_MESSAGE);
				}

				KitFrame.this.getCenterPanel().removeAll();
				KitFrame.this.getCenterPanel().add(srPanel);
				KitFrame.this.setVisible(true);
				KitFrame.this.pack();
			}
		});
		mnFile.add(mntmNuovoRound);
		mnFile.add(mntmEsci);

		mnSegreti = new JMenu("Domande");
		mnSegreti.setEnabled(false);
		menuBar.add(mnSegreti);

		JMenuItem mntmAggiungiRisposta = new JMenuItem("Aggiungi risposta");
		mntmAggiungiRisposta.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (!checkQuestionsList())
					return;
				KitDB db = new KitDB();
				AnswerSelectionPanel asPanel = new AnswerSelectionPanel();
				String secret = (String) KitFrame.this.getQuestionList()
						.getSelectedValue();
				List<String> domainItem = db.getDomainElements();
				List<String> insertedAnswers = db.getAnswers(secret);
				domainItem.removeAll(insertedAnswers);
				for (String item : domainItem) {
					asPanel.getDomainComboBox().addItem(item);
				}

				KitFrame.this.getCenterPanel().removeAll();
				KitFrame.this.getCenterPanel().add(asPanel);
				KitFrame.this.setVisible(true);
				KitFrame.this.pack();
			}
		});
		mnSegreti.add(mntmAggiungiRisposta);

		JMenuItem mntmVisualizzaRisposta = new JMenuItem("Visualizza risposte");
		mntmVisualizzaRisposta.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (!checkQuestionsList())
					return;
				String question = (String) KitFrame.this.getQuestionList()
						.getSelectedValue();
				KitDB db = new KitDB();
				List<String> answers = db.getAnswers(question);
				if(answers.size() == 0){
					JOptionPane.showMessageDialog(KitFrame.this,
							"Non sono presenti risposte per questa domanda.",
							"Nessuna risposta",
							JOptionPane.INFORMATION_MESSAGE);
					return;
				}
				List<String> richAnswers = new LinkedList<>();
				AnswerPanel aPanel = new AnswerPanel(question);
				for(String answer : answers){
					Double entropy = db.getAnswerEntropy(question, answer);
					DecimalFormat df = new DecimalFormat("#.#####");
					richAnswers.add(String.format("%s - %s",answer, df.format(entropy)));
				}
				aPanel.getAnswersList().setListData(richAnswers.toArray(new String[0]));
				aPanel.getAnswersList().setSelectedIndex(0);
				
				KitFrame.this.getCenterPanel().removeAll();
				KitFrame.this.getCenterPanel().add(aPanel);
				KitFrame.this.setVisible(true);
				KitFrame.this.pack();
			}
		});
		mnSegreti.add(mntmVisualizzaRisposta);

		JMenuItem mntmAggiungiSegreto = new JMenuItem("Aggiungi domanda");
		mntmAggiungiSegreto.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				QuestionPanel qPanel = new QuestionPanel();
				KitFrame.this.getCenterPanel().removeAll();
				KitFrame.this.getCenterPanel().add(qPanel);
				KitFrame.this.setVisible(true);
				KitFrame.this.pack();
			}
		});
		mnSegreti.add(mntmAggiungiSegreto);

		mnRound = new JMenu("Round");
		mnRound.setEnabled(false);
		menuBar.add(mnRound);

		mntmGeneraDomanda = new JMenuItem("Genera domanda");
		mntmGeneraDomanda.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (!checkQuestionsList())
					return;
				
				RoundQuestionPanel rqPanel = new RoundQuestionPanel();
				String question = (String) KitFrame.this.getQuestionList().getSelectedValue();
				rqPanel.getQuestionTextArea().setText(question);
				KitFrame.this.getCenterPanel().removeAll();
				KitFrame.this.getCenterPanel().add(rqPanel);
				KitFrame.this.setVisible(true);
				KitFrame.this.pack();
			}
		});
		mnRound.add(mntmGeneraDomanda);

		mntmGeneraRisposta = new JMenuItem("Genera risposta");
		mntmGeneraRisposta.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				KitFrame.this.getCenterPanel().removeAll();
				KitFrame.this.getCenterPanel().add(new RoundAnswerPanel());
				KitFrame.this.setVisible(true);
				KitFrame.this.pack();
			}
		});
		mntmGeneraRisposta.setEnabled(false);
		mnRound.add(mntmGeneraRisposta);
		
		mntmConcludiRound = new JMenuItem("Concludi round");
		mntmConcludiRound.setEnabled(false);
		mntmConcludiRound.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				KitFrame.this.getCenterPanel().removeAll();
				KitFrame.this.getCenterPanel().add(new RoundConclusionPanel());
				KitFrame.this.setVisible(true);
				KitFrame.this.pack();
			}
		});
		mnRound.add(mntmConcludiRound);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(new BorderLayout(0, 0));

		JPanel panel = new JPanel();
		panel.setPreferredSize(new Dimension(200, 10));
		panel.setBackground(Color.ORANGE);
		contentPane.add(panel, BorderLayout.WEST);
		panel.setLayout(new BorderLayout(10, 10));

		JScrollPane scrollPane = new JScrollPane();
		panel.add(scrollPane, BorderLayout.CENTER);

		secrectList_1 = new JList();
		secrectList_1.setSize(new Dimension(150, 400));
		secrectList_1.addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent arg0) {
				if (!KitFrame.this.getMnSegreti().isEnabled())
					return;
				KitDB db = new KitDB();
				String question = (String) KitFrame.this.getQuestionList()
						.getSelectedValue();
				if (question == null) {
					return;
				}

				QuestionPanel qPanel = new QuestionPanel();
				qPanel.getQuestionText().setText(question);
				qPanel.getQuestionText().setEditable(false);

				KitFrame.this.getCenterPanel().removeAll();
				KitFrame.this.getCenterPanel().add(qPanel);
				KitFrame.this.setVisible(true);
				KitFrame.this.pack();
			}
		});

		secrectList_1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		secrectList_1.setBorder(new LineBorder(new Color(0, 0, 0)));
		scrollPane.setViewportView(secrectList_1);

		centerPanel = new JPanel();
		contentPane.add(centerPanel, BorderLayout.CENTER);
		centerPanel.setLayout(new CardLayout(10, 10));

		panel_1 = new JPanel();
		FlowLayout fl_panel_1 = (FlowLayout) panel_1.getLayout();
		fl_panel_1.setAlignment(FlowLayout.LEFT);
		contentPane.add(panel_1, BorderLayout.SOUTH);

		txtrItsOver = new JTextArea();
		txtrItsOver.setEditable(false);
		txtrItsOver.setBorder(null);
		txtrItsOver.setBackground(UIManager.getColor("Button.background"));
		txtrItsOver.setColumns(30);
		txtrItsOver.setRows(1);
		panel_1.add(txtrItsOver);
		
		mntmNuovoRound.doClick();
	}

	private boolean checkQuestionsList() {
		if (KitFrame.this.getQuestionList().getSelectedIndex() == -1) {
			JOptionPane.showMessageDialog(KitFrame.this,
					"E' necessario selezionare una domanda dall'elenco.\n",
					"Errore", JOptionPane.ERROR_MESSAGE);
			return false;
		}
		return true;
	}

	protected JMenu getMnFile() {
		return mnFile;
	}

	protected JMenu getMnSegreti() {
		return mnSegreti;
	}

	protected JMenu getMnRound() {
		return mnRound;
	}

	protected JPanel getCenterPanel() {
		return centerPanel;
	}

	protected JMenuItem getMntmNuovoRound() {
		return mntmNuovoRound;
	}

	protected JList getQuestionList() {
		return secrectList_1;
	}

	public void populateQuestionsList() {
		JList questionList = KitFrame.this.getQuestionList();
		KitDB db = new KitDB();
		questionList.setListData(db.getSecrets().toArray());
	}
	public JMenuItem getGeneraDomandaMenuItem() {
		return mntmGeneraDomanda;
	}
	public JPanel getStatusPanel() {
		return panel_1;
	}
	public JTextArea getStatusLabel() {
		return txtrItsOver;
	}
	public JMenuItem getGeneraRispostaMenuItem() {
		return mntmGeneraRisposta;
	}
	public JMenuItem getMntmConcludiRound() {
		return mntmConcludiRound;
	}
}
